(ns example.ip
  (:require [packet.core :as p :refer [defpacket parse build]]
            [packet.types :as t :refer [deftype u bcd ipaddr]]
            [packet.checksum :as cs]))

(deftype header-options "头部选项，仅做示例"
  (option
    1
    (u 1 as opt-1)
    (padding 4))
  (option
    2
    (bcd 2 as opt-2)
    (padding 4)))

(defpacket ip
  (flag as header
        (b4-7 as ver "版本号" with {4 :ipv4 6 :ipv6} default :ipv4)
        (b0-3 "头部长度" with * 4 length until data))
  (u 1 as tos "区分服务")
  (u 2 "数据长度" length-of data)
  (u 2 as id "标识符")
  (flag as ctrl
        (b1 as df "允许分片" with [:disable-fragment :enable-fragment])
        (b2 as mf "更多分片" with [:no-more-fragment :more-fragment])
        (b3-15 as frag-offset "分片偏移" with * 8))
  (u 1 as ttl "生存时间")
  (u 1 as protocol "上层协议" with {17 :tcp} default :tcp)
  (u 2 checksum to dest-ip use cs/cs16)
  (ipaddr as source-ip "源地址")
  (ipaddr as dest-ip "目标地址")
  (header-options)
  
  (raw as data "上层报文"))


(def m {:tos 2
        :id 1111
        :ctrl {:df :enable-fragment
               :mf :more-fragment
               :frag-offset 96}
        :ttl 4
        :source-ip (t/ip-reader "192.168.0.1")
        :dest-ip (t/ip-reader "10.18.16.3")
        :opt-2 55
        :data [9 8 7 6]})

#_(p/test-packet ip m)


(defpacket tt
  (expect 1 x as b)
  (ipaddr as a sep-by 0 1)
  0
  )
(def bs [1 2 3 4 0 1 5 6 7 8 0 1 2 3 4 ])

(defpacket foo
  (skip-until 0x68) ;跳过无关字节直到遇到有效报文起始标志0x68
  (u 2 as a) ;u是预定义的字段类型，表示无符号整数，2表示本字段占用2字节的空间，a是字段的名称，由as引入
  (u 1 as b)
  0x16)
